/**
 * @license
 * =========================================================
 * bootstrap-datetimepicker.js
 * http://www.eyecon.ro/bootstrap-datepicker
 * =========================================================
 * Copyright 2012 Stefan Petre
 *
 * Contributions:
 *  - Andrew Rowls
 *  - Thiago de Arruda
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * =========================================================
 */
(function ($) { var smartPhone = window.orientation != undefined; var DateTimePicker = function (element, options) { this.id = dpgId++; this.init(element, options) }; var dateToDate = function (dt) { if (typeof dt === "string") { return new Date(dt) } return dt }; DateTimePicker.prototype = { constructor: DateTimePicker, init: function (element, options) { var icon; if (!(options.pickTime || options.pickDate)) throw new Error("Must choose at least one picker"); this.options = options; this.$element = $(element); this.language = options.language in dates ? options.language : "en"; this.pickDate = options.pickDate; this.pickTime = options.pickTime; this.isInput = this.$element.is("input"); this.component = false; if (this.$element.find(".input-append") || this.$element.find(".input-prepend")) this.component = this.$element.find(".add-on"); this.format = options.format; if (!this.format) { if (this.isInput) this.format = this.$element.data("format"); else this.format = this.$element.find("input").data("format"); if (!this.format) this.format = "MM/dd/yyyy" } this._compileFormat(); if (this.component) { icon = this.component.find("i") } if (this.pickTime) { if (icon && icon.length) this.timeIcon = icon.data("time-icon"); if (!this.timeIcon) this.timeIcon = "icon-time"; icon.addClass(this.timeIcon) } if (this.pickDate) { if (icon && icon.length) this.dateIcon = icon.data("date-icon"); if (!this.dateIcon) this.dateIcon = "icon-calendar"; icon.removeClass(this.timeIcon); icon.addClass(this.dateIcon) } this.widget = $(getTemplate(this.timeIcon, options.pickDate, options.pickTime, options.pick12HourFormat, options.pickSeconds, options.collapse)).appendTo("body"); this.minViewMode = options.minViewMode || this.$element.data("date-minviewmode") || 0; if (typeof this.minViewMode === "string") { switch (this.minViewMode) { case "months": this.minViewMode = 1; break; case "years": this.minViewMode = 2; break; default: this.minViewMode = 0; break } } this.viewMode = options.viewMode || this.$element.data("date-viewmode") || 0; if (typeof this.viewMode === "string") { switch (this.viewMode) { case "months": this.viewMode = 1; break; case "years": this.viewMode = 2; break; default: this.viewMode = 0; break } } this.startViewMode = this.viewMode; this.weekStart = options.weekStart || this.$element.data("date-weekstart") || 0; this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1; this.setStartDate(options.startDate || this.$element.data("date-startdate")); this.setEndDate(options.endDate || this.$element.data("date-enddate")); this.fillDow(); this.fillMonths(); this.fillHours(); this.fillMinutes(); this.fillSeconds(); this.update(); this.showMode(); this._attachDatePickerEvents() }, show: function (e) { this.widget.show(); this.height = this.component ? this.component.outerHeight() : this.$element.outerHeight(); this.place(); this.$element.trigger({ type: "show", date: this._date }); this._attachDatePickerGlobalEvents(); if (e) { e.stopPropagation(); e.preventDefault() } }, disable: function () { this.$element.find("input").prop("disabled", true); this._detachDatePickerEvents() }, enable: function () { this.$element.find("input").prop("disabled", false); this._attachDatePickerEvents() }, hide: function () { var collapse = this.widget.find(".collapse"); for (var i = 0; i < collapse.length; i++) { var collapseData = collapse.eq(i).data("collapse"); if (collapseData && collapseData.transitioning) return } this.widget.hide(); this.viewMode = this.startViewMode; this.showMode(); this.set(); this.$element.trigger({ type: "hide", date: this._date }); this._detachDatePickerGlobalEvents() }, set: function () { var formatted = ""; if (!this._unset) formatted = this.formatDate(this._date); if (!this.isInput) { if (this.component) { var input = this.$element.find("input"); input.val(formatted); this._resetMaskPos(input) } this.$element.data("date", formatted) } else { this.$element.val(formatted); this._resetMaskPos(this.$element) } }, setValue: function (newDate) { if (!newDate) { this._unset = true } else { this._unset = false } if (typeof newDate === "string") { this._date = this.parseDate(newDate) } else if (newDate) { this._date = new Date(newDate) } this.set(); this.viewDate = UTCDate(this._date.getUTCFullYear(), this._date.getUTCMonth(), 1, 0, 0, 0, 0); this.fillDate(); this.fillTime() }, getDate: function () { if (this._unset) return null; return new Date(this._date.valueOf()) }, setDate: function (date) { if (!date) this.setValue(null); else this.setValue(date.valueOf()) }, setStartDate: function (date) { if (date instanceof Date) { this.startDate = date } else if (typeof date === "string") { this.startDate = new UTCDate(date); if (!this.startDate.getUTCFullYear()) { this.startDate = -Infinity } } else { this.startDate = -Infinity } if (this.viewDate) { this.update() } }, setEndDate: function (date) { if (date instanceof Date) { this.endDate = date } else if (typeof date === "string") { this.endDate = new UTCDate(date); if (!this.endDate.getUTCFullYear()) { this.endDate = Infinity } } else { this.endDate = Infinity } if (this.viewDate) { this.update() } }, getLocalDate: function () { if (this._unset) return null; var d = this._date; return new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds()) }, setLocalDate: function (localDate) { if (!localDate) this.setValue(null); else this.setValue(Date.UTC(localDate.getFullYear(), localDate.getMonth(), localDate.getDate(), localDate.getHours(), localDate.getMinutes(), localDate.getSeconds(), localDate.getMilliseconds())) }, place: function () { var position = "absolute"; var offset = this.component ? this.component.offset() : this.$element.offset(); this.width = this.component ? this.component.outerWidth() : this.$element.outerWidth(); offset.top = offset.top + this.height; var $window = $(window); if (this.options.width != undefined) { this.widget.width(this.options.width) } if (this.options.orientation == "left") { this.widget.addClass("left-oriented"); offset.left = offset.left - this.widget.width() + 20 } if (this._isInFixed()) { position = "fixed"; offset.top -= $window.scrollTop(); offset.left -= $window.scrollLeft() } if ($window.width() < offset.left + this.widget.outerWidth()) { offset.right = $window.width() - offset.left - this.width; offset.left = "auto"; this.widget.addClass("pull-right") } else { offset.right = "auto"; this.widget.removeClass("pull-right") } this.widget.css({ position: position, top: offset.top, left: offset.left, right: offset.right }) }, notifyChange: function () { this.$element.trigger({ type: "changeDate", date: this.getDate(), localDate: this.getLocalDate() }) }, update: function (newDate) { var dateStr = newDate; if (!dateStr) { if (this.isInput) { dateStr = this.$element.val() } else { dateStr = this.$element.find("input").val() } if (dateStr) { this._date = this.parseDate(dateStr) } if (!this._date) { var tmp = new Date; this._date = UTCDate(tmp.getFullYear(), tmp.getMonth(), tmp.getDate(), tmp.getHours(), tmp.getMinutes(), tmp.getSeconds(), tmp.getMilliseconds()) } } this.viewDate = UTCDate(this._date.getUTCFullYear(), this._date.getUTCMonth(), 1, 0, 0, 0, 0); this.fillDate(); this.fillTime() }, fillDow: function () { var dowCnt = this.weekStart; var html = $("<tr>"); while (dowCnt < this.weekStart + 7) { html.append('<th class="dow">' + dates[this.language].daysMin[dowCnt++ % 7] + "</th>") } this.widget.find(".datepicker-days thead").append(html) }, fillMonths: function () { var html = ""; var i = 0; while (i < 12) { html += '<span class="month">' + dates[this.language].monthsShort[i++] + "</span>" } this.widget.find(".datepicker-months td").append(html) }, fillDate: function () { var year = this.viewDate.getUTCFullYear(); var month = this.viewDate.getUTCMonth(); var currentDate = UTCDate(this._date.getUTCFullYear(), this._date.getUTCMonth(), this._date.getUTCDate(), 0, 0, 0, 0); var startYear = typeof this.startDate === "object" ? this.startDate.getUTCFullYear() : -Infinity; var startMonth = typeof this.startDate === "object" ? this.startDate.getUTCMonth() : -1; var endYear = typeof this.endDate === "object" ? this.endDate.getUTCFullYear() : Infinity; var endMonth = typeof this.endDate === "object" ? this.endDate.getUTCMonth() : 12; this.widget.find(".datepicker-days").find(".disabled").removeClass("disabled"); this.widget.find(".datepicker-months").find(".disabled").removeClass("disabled"); this.widget.find(".datepicker-years").find(".disabled").removeClass("disabled"); this.widget.find(".datepicker-days th:eq(1)").text(dates[this.language].months[month] + " " + year); var prevMonth = UTCDate(year, month - 1, 28, 0, 0, 0, 0); var day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth()); prevMonth.setUTCDate(day); prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7) % 7); if (year == startYear && month <= startMonth || year < startYear) { this.widget.find(".datepicker-days th:eq(0)").addClass("disabled") } if (year == endYear && month >= endMonth || year > endYear) { this.widget.find(".datepicker-days th:eq(2)").addClass("disabled") } var nextMonth = new Date(prevMonth.valueOf()); nextMonth.setUTCDate(nextMonth.getUTCDate() + 42); nextMonth = nextMonth.valueOf(); var html = []; var row; var clsName; while (prevMonth.valueOf() < nextMonth) { if (prevMonth.getUTCDay() === this.weekStart) { row = $("<tr>"); html.push(row) } clsName = ""; if (prevMonth.getUTCFullYear() < year || prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() < month) { clsName += " old" } else if (prevMonth.getUTCFullYear() > year || prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() > month) { clsName += " new" } if (prevMonth.valueOf() === currentDate.valueOf()) { clsName += " active" } if (prevMonth.valueOf() + 864e5 <= this.startDate) { clsName += " disabled" } if (prevMonth.valueOf() > this.endDate) { clsName += " disabled" } row.append('<td class="day' + clsName + '">' + prevMonth.getUTCDate() + "</td>"); prevMonth.setUTCDate(prevMonth.getUTCDate() + 1) } this.widget.find(".datepicker-days tbody").empty().append(html); var currentYear = this._date.getUTCFullYear(); var months = this.widget.find(".datepicker-months").find("th:eq(1)").text(year).end().find("span").removeClass("active"); if (currentYear === year) { months.eq(this._date.getUTCMonth()).addClass("active") } if (currentYear - 1 < startYear) { this.widget.find(".datepicker-months th:eq(0)").addClass("disabled") } if (currentYear + 1 > endYear) { this.widget.find(".datepicker-months th:eq(2)").addClass("disabled") } for (var i = 0; i < 12; i++) { if (year == startYear && startMonth > i || year < startYear) { $(months[i]).addClass("disabled") } else if (year == endYear && endMonth < i || year > endYear) { $(months[i]).addClass("disabled") } } html = ""; year = parseInt(year / 10, 10) * 10; var yearCont = this.widget.find(".datepicker-years").find("th:eq(1)").text(year + "-" + (year + 9)).end().find("td"); this.widget.find(".datepicker-years").find("th").removeClass("disabled"); if (startYear > year) { this.widget.find(".datepicker-years").find("th:eq(0)").addClass("disabled") } if (endYear < year + 9) { this.widget.find(".datepicker-years").find("th:eq(2)").addClass("disabled") } year -= 1; for (var i = -1; i < 11; i++) { html += '<span class="year' + (i === -1 || i === 10 ? " old" : "") + (currentYear === year ? " active" : "") + (year < startYear || year > endYear ? " disabled" : "") + '">' + year + "</span>"; year += 1 } yearCont.html(html) }, fillHours: function () { var table = this.widget.find(".timepicker .timepicker-hours table"); table.parent().hide(); var html = ""; if (this.options.pick12HourFormat) { var current = 1; for (var i = 0; i < 3; i += 1) { html += "<tr>"; for (var j = 0; j < 4; j += 1) { var c = current.toString(); html += '<td class="hour">' + padLeft(c, 2, "0") + "</td>"; current++ } html += "</tr>" } } else { var current = 0; for (var i = 0; i < 6; i += 1) { html += "<tr>"; for (var j = 0; j < 4; j += 1) { var c = current.toString(); html += '<td class="hour">' + padLeft(c, 2, "0") + "</td>"; current++ } html += "</tr>" } } table.html(html) }, fillMinutes: function () { var table = this.widget.find(".timepicker .timepicker-minutes table"); table.parent().hide(); var html = ""; var current = 0; for (var i = 0; i < 5; i++) { html += "<tr>"; for (var j = 0; j < 4; j += 1) { var c = current.toString(); html += '<td class="minute">' + padLeft(c, 2, "0") + "</td>"; current += 3 } html += "</tr>" } table.html(html) }, fillSeconds: function () { var table = this.widget.find(".timepicker .timepicker-seconds table"); table.parent().hide(); var html = ""; var current = 0; for (var i = 0; i < 5; i++) { html += "<tr>"; for (var j = 0; j < 4; j += 1) { var c = current.toString(); html += '<td class="second">' + padLeft(c, 2, "0") + "</td>"; current += 3 } html += "</tr>" } table.html(html) }, fillTime: function () { if (!this._date) return; var timeComponents = this.widget.find(".timepicker span[data-time-component]"); var table = timeComponents.closest("table"); var is12HourFormat = this.options.pick12HourFormat; var hour = this._date.getUTCHours(); var period = "AM"; if (is12HourFormat) { if (hour >= 12) period = "PM"; if (hour === 0) hour = 12; else if (hour != 12) hour = hour % 12; this.widget.find(".timepicker [data-action=togglePeriod]").text(period) } hour = padLeft(hour.toString(), 2, "0"); var minute = padLeft(this._date.getUTCMinutes().toString(), 2, "0"); var second = padLeft(this._date.getUTCSeconds().toString(), 2, "0"); timeComponents.filter("[data-time-component=hours]").text(hour); timeComponents.filter("[data-time-component=minutes]").text(minute); timeComponents.filter("[data-time-component=seconds]").text(second) }, click: function (e) { e.stopPropagation(); e.preventDefault(); this._unset = false; var target = $(e.target).closest("span, td, th"); if (target.length === 1) { if (!target.is(".disabled")) { switch (target[0].nodeName.toLowerCase()) { case "th": switch (target[0].className) { case "switch": this.showMode(1); break; case "prev": case "next": var vd = this.viewDate; var navFnc = DPGlobal.modes[this.viewMode].navFnc; var step = DPGlobal.modes[this.viewMode].navStep; if (target[0].className === "prev") step = step * -1; vd["set" + navFnc](vd["get" + navFnc]() + step); this.fillDate(); this.set(); break } break; case "span": if (target.is(".month")) { var month = target.parent().find("span").index(target); this.viewDate.setUTCMonth(month) } else { var year = parseInt(target.text(), 10) || 0; this.viewDate.setUTCFullYear(year) } if (this.viewMode !== 0) { this._date = UTCDate(this.viewDate.getUTCFullYear(), this.viewDate.getUTCMonth(), this.viewDate.getUTCDate(), this._date.getUTCHours(), this._date.getUTCMinutes(), this._date.getUTCSeconds(), this._date.getUTCMilliseconds()); this.notifyChange() } this.showMode(-1); this.fillDate(); this.set(); break; case "td": if (target.is(".day")) { var day = parseInt(target.text(), 10) || 1; var month = this.viewDate.getUTCMonth(); var year = this.viewDate.getUTCFullYear(); if (target.is(".old")) { if (month === 0) { month = 11; year -= 1 } else { month -= 1 } } else if (target.is(".new")) { if (month == 11) { month = 0; year += 1 } else { month += 1 } } this._date = UTCDate(year, month, day, this._date.getUTCHours(), this._date.getUTCMinutes(), this._date.getUTCSeconds(), this._date.getUTCMilliseconds()); this.viewDate = UTCDate(year, month, Math.min(28, day), 0, 0, 0, 0); this.fillDate(); this.set(); this.notifyChange() } break } } } }, actions: { incrementHours: function (e) { this._date.setUTCHours(this._date.getUTCHours() + 1) }, incrementMinutes: function (e) { this._date.setUTCMinutes(this._date.getUTCMinutes() + 1) }, incrementSeconds: function (e) { this._date.setUTCSeconds(this._date.getUTCSeconds() + 1) }, decrementHours: function (e) { this._date.setUTCHours(this._date.getUTCHours() - 1) }, decrementMinutes: function (e) { this._date.setUTCMinutes(this._date.getUTCMinutes() - 1) }, decrementSeconds: function (e) { this._date.setUTCSeconds(this._date.getUTCSeconds() - 1) }, togglePeriod: function (e) { var hour = this._date.getUTCHours(); if (hour >= 12) hour -= 12; else hour += 12; this._date.setUTCHours(hour) }, showPicker: function () { this.widget.find(".timepicker > div:not(.timepicker-picker)").hide(); this.widget.find(".timepicker .timepicker-picker").show() }, showHours: function () { this.widget.find(".timepicker .timepicker-picker").hide(); this.widget.find(".timepicker .timepicker-hours").show() }, showMinutes: function () { this.widget.find(".timepicker .timepicker-picker").hide(); this.widget.find(".timepicker .timepicker-minutes").show() }, showSeconds: function () { this.widget.find(".timepicker .timepicker-picker").hide(); this.widget.find(".timepicker .timepicker-seconds").show() }, selectHour: function (e) { var tgt = $(e.target); var value = parseInt(tgt.text(), 10); if (this.options.pick12HourFormat) { var current = this._date.getUTCHours(); if (current >= 12) { if (value != 12) value = (value + 12) % 24 } else { if (value === 12) value = 0; else value = value % 12 } } this._date.setUTCHours(value); this.actions.showPicker.call(this) }, selectMinute: function (e) { var tgt = $(e.target); var value = parseInt(tgt.text(), 10); this._date.setUTCMinutes(value); this.actions.showPicker.call(this) }, selectSecond: function (e) { var tgt = $(e.target); var value = parseInt(tgt.text(), 10); this._date.setUTCSeconds(value); this.actions.showPicker.call(this) } }, doAction: function (e) { e.stopPropagation(); e.preventDefault(); if (!this._date) this._date = UTCDate(1970, 0, 0, 0, 0, 0, 0); var action = $(e.currentTarget).data("action"); var rv = this.actions[action].apply(this, arguments); this.set(); this.fillTime(); this.notifyChange(); return rv }, stopEvent: function (e) { e.stopPropagation(); e.preventDefault() }, keydown: function (e) { var self = this, k = e.which, input = $(e.target); if (k == 8 || k == 46) { setTimeout(function () { self._resetMaskPos(input) }) } }, keypress: function (e) { var k = e.which; if (k == 8 || k == 46) { return } var input = $(e.target); var c = String.fromCharCode(k); var val = input.val() || ""; val += c; var mask = this._mask[this._maskPos]; if (!mask) { return false } if (mask.end != val.length) { return } if (!mask.pattern.test(val.slice(mask.start))) { val = val.slice(0, val.length - 1); while ((mask = this._mask[this._maskPos]) && mask.character) { val += mask.character; this._maskPos++ } val += c; if (mask.end != val.length) { input.val(val); return false } else { if (!mask.pattern.test(val.slice(mask.start))) { input.val(val.slice(0, mask.start)); return false } else { input.val(val); this._maskPos++; return false } } } else { this._maskPos++ } }, change: function (e) { var input = $(e.target); var val = input.val(); if (this._formatPattern.test(val)) { this.update(); this.setValue(this._date.getTime()); this.notifyChange(); this.set() } else if (val && val.trim()) { this.setValue(this._date.getTime()); if (this._date) this.set(); else input.val("") } else { if (this._date) { this.setValue(null); this.notifyChange(); this._unset = true } } this._resetMaskPos(input) }, showMode: function (dir) { if (dir) { this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir)) } this.widget.find(".datepicker > div").hide().filter(".datepicker-" + DPGlobal.modes[this.viewMode].clsName).show() }, destroy: function () { this._detachDatePickerEvents(); this._detachDatePickerGlobalEvents(); this.widget.remove(); this.$element.removeData("datetimepicker"); this.component.removeData("datetimepicker") }, formatDate: function (d) { return this.format.replace(formatReplacer, function (match) { var methodName, property, rv, len = match.length; if (match === "ms") len = 1; property = dateFormatComponents[match].property; if (property === "Hours12") { rv = d.getUTCHours(); if (rv === 0) rv = 12; else if (rv !== 12) rv = rv % 12 } else if (property === "Period12") { if (d.getUTCHours() >= 12) return "PM"; else return "AM" } else { methodName = "get" + property; rv = d[methodName]() } if (methodName === "getUTCMonth") rv = rv + 1; if (methodName === "getUTCYear") rv = rv + 1900 - 2e3; return padLeft(rv.toString(), len, "0") }) }, parseDate: function (str) { var match, i, property, methodName, value, parsed = {}; if (!(match = this._formatPattern.exec(str))) return null; for (i = 1; i < match.length; i++) { property = this._propertiesByIndex[i]; if (!property) continue; value = match[i]; if (/^\d+$/.test(value)) value = parseInt(value, 10); parsed[property] = value } return this._finishParsingDate(parsed) }, _resetMaskPos: function (input) { var val = input.val(); for (var i = 0; i < this._mask.length; i++) { if (this._mask[i].end > val.length) { this._maskPos = i; break } else if (this._mask[i].end === val.length) { this._maskPos = i + 1; break } } }, _finishParsingDate: function (parsed) { var year, month, date, hours, minutes, seconds, milliseconds; year = parsed.UTCFullYear; if (parsed.UTCYear) year = 2e3 + parsed.UTCYear; if (!year) year = 1970; if (parsed.UTCMonth) month = parsed.UTCMonth - 1; else month = 0; date = parsed.UTCDate || 1; hours = parsed.UTCHours || 0; minutes = parsed.UTCMinutes || 0; seconds = parsed.UTCSeconds || 0; milliseconds = parsed.UTCMilliseconds || 0; if (parsed.Hours12) { hours = parsed.Hours12 } if (parsed.Period12) { if (/pm/i.test(parsed.Period12)) { if (hours != 12) hours = (hours + 12) % 24 } else { hours = hours % 12 } } return UTCDate(year, month, date, hours, minutes, seconds, milliseconds) }, _compileFormat: function () { var match, component, components = [], mask = [], str = this.format, propertiesByIndex = {}, i = 0, pos = 0; while (match = formatComponent.exec(str)) { component = match[0]; if (component in dateFormatComponents) { i++; propertiesByIndex[i] = dateFormatComponents[component].property; components.push("\\s*" + dateFormatComponents[component].getPattern(this) + "\\s*"); mask.push({ pattern: new RegExp(dateFormatComponents[component].getPattern(this)), property: dateFormatComponents[component].property, start: pos, end: pos += component.length }) } else { components.push(escapeRegExp(component)); mask.push({ pattern: new RegExp(escapeRegExp(component)), character: component, start: pos, end: ++pos }) } str = str.slice(component.length) } this._mask = mask; this._maskPos = 0; this._formatPattern = new RegExp("^\\s*" + components.join("") + "\\s*$"); this._propertiesByIndex = propertiesByIndex }, _attachDatePickerEvents: function () { var self = this; this.widget.on("click", ".datepicker *", $.proxy(this.click, this)); this.widget.on("click", "[data-action]", $.proxy(this.doAction, this)); this.widget.on("mousedown", $.proxy(this.stopEvent, this)); if (this.pickDate && this.pickTime) { this.widget.on("click.togglePicker", ".accordion-toggle", function (e) { e.stopPropagation(); var $this = $(this); var $parent = $this.closest("ul"); var expanded = $parent.find(".collapse.in"); var closed = $parent.find(".collapse:not(.in)"); if (expanded && expanded.length) { var collapseData = expanded.data("collapse"); if (collapseData && collapseData.transitioning) return; expanded.collapse("hide"); closed.collapse("show"); $this.find("i").toggleClass(self.timeIcon + " " + self.dateIcon); self.$element.find(".add-on i").toggleClass(self.timeIcon + " " + self.dateIcon) } }) } if (this.isInput) { this.$element.on({ focus: $.proxy(this.show, this), change: $.proxy(this.change, this) }); if (this.options.maskInput) { this.$element.on({ keydown: $.proxy(this.keydown, this), keypress: $.proxy(this.keypress, this) }) } } else { this.$element.on({ change: $.proxy(this.change, this) }, "input"); if (this.options.maskInput) { this.$element.on({ keydown: $.proxy(this.keydown, this), keypress: $.proxy(this.keypress, this) }, "input") } if (this.component) { this.component.on("click", $.proxy(this.show, this)) } else { this.$element.on("click", $.proxy(this.show, this)) } } }, _attachDatePickerGlobalEvents: function () { $(window).on("resize.datetimepicker" + this.id, $.proxy(this.place, this)); if (!this.isInput) { $(document).on("mousedown.datetimepicker" + this.id, $.proxy(this.hide, this)) } }, _detachDatePickerEvents: function () { this.widget.off("click", ".datepicker *", this.click); this.widget.off("click", "[data-action]"); this.widget.off("mousedown", this.stopEvent); if (this.pickDate && this.pickTime) { this.widget.off("click.togglePicker") } if (this.isInput) { this.$element.off({ focus: this.show, change: this.change }); if (this.options.maskInput) { this.$element.off({ keydown: this.keydown, keypress: this.keypress }) } } else { this.$element.off({ change: this.change }, "input"); if (this.options.maskInput) { this.$element.off({ keydown: this.keydown, keypress: this.keypress }, "input") } if (this.component) { this.component.off("click", this.show) } else { this.$element.off("click", this.show) } } }, _detachDatePickerGlobalEvents: function () { $(window).off("resize.datetimepicker" + this.id); if (!this.isInput) { $(document).off("mousedown.datetimepicker" + this.id) } }, _isInFixed: function () { if (this.$element) { var parents = this.$element.parents(); var inFixed = false; for (var i = 0; i < parents.length; i++) { if ($(parents[i]).css("position") == "fixed") { inFixed = true; break } } return inFixed } else { return false } } }; $.fn.datetimepicker = function (option, val) { return this.each(function () { var $this = $(this), data = $this.data("datetimepicker"), options = typeof option === "object" && option; if (!data) { $this.data("datetimepicker", data = new DateTimePicker(this, $.extend({}, $.fn.datetimepicker.defaults, options))) } if (typeof option === "string") data[option](val) }) }; $.fn.datetimepicker.defaults = { maskInput: false, pickDate: true, pickTime: true, pick12HourFormat: false, pickSeconds: true, startDate: -Infinity, endDate: Infinity, collapse: true }; $.fn.datetimepicker.Constructor = DateTimePicker; var dpgId = 0; var dates = $.fn.datetimepicker.dates = { en: { days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] } }; var dateFormatComponents = { dd: { property: "UTCDate", getPattern: function () { return "(0?[1-9]|[1-2][0-9]|3[0-1])\\b" } }, MM: { property: "UTCMonth", getPattern: function () { return "(0?[1-9]|1[0-2])\\b" } }, yy: { property: "UTCYear", getPattern: function () { return "(\\d{2})\\b" } }, yyyy: { property: "UTCFullYear", getPattern: function () { return "(\\d{4})\\b" } }, hh: { property: "UTCHours", getPattern: function () { return "(0?[0-9]|1[0-9]|2[0-3])\\b" } }, mm: { property: "UTCMinutes", getPattern: function () { return "(0?[0-9]|[1-5][0-9])\\b" } }, ss: { property: "UTCSeconds", getPattern: function () { return "(0?[0-9]|[1-5][0-9])\\b" } }, ms: { property: "UTCMilliseconds", getPattern: function () { return "([0-9]{1,3})\\b" } }, HH: { property: "Hours12", getPattern: function () { return "(0?[1-9]|1[0-2])\\b" } }, PP: { property: "Period12", getPattern: function () { return "(AM|PM|am|pm|Am|aM|Pm|pM)\\b" } } }; var keys = []; for (var k in dateFormatComponents) keys.push(k); keys[keys.length - 1] += "\\b"; keys.push("."); var formatComponent = new RegExp(keys.join("\\b|")); keys.pop(); var formatReplacer = new RegExp(keys.join("\\b|"), "g"); function escapeRegExp(str) { return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") } function padLeft(s, l, c) { if (l < s.length) return s; else return Array(l - s.length + 1).join(c || " ") + s } function getTemplate(timeIcon, pickDate, pickTime, is12Hours, showSeconds, collapse) { if (pickDate && pickTime) { return '<div class="bootstrap-datetimepicker-widget dropdown-menu">' + "<ul>" + "<li" + (collapse ? ' class="collapse in"' : "") + ">" + '<div class="datepicker">' + DPGlobal.template + "</div>" + "</li>" + '<li class="picker-switch accordion-toggle"><a><i class="' + timeIcon + '"></i></a></li>' + "<li" + (collapse ? ' class="collapse"' : "") + ">" + '<div class="timepicker">' + TPGlobal.getTemplate(is12Hours, showSeconds) + "</div>" + "</li>" + "</ul>" + "</div>" } else if (pickTime) { return '<div class="bootstrap-datetimepicker-widget dropdown-menu">' + '<div class="timepicker">' + TPGlobal.getTemplate(is12Hours, showSeconds) + "</div>" + "</div>" } else { return '<div class="bootstrap-datetimepicker-widget dropdown-menu">' + '<div class="datepicker">' + DPGlobal.template + "</div>" + "</div>" } } function UTCDate() { return new Date(Date.UTC.apply(Date, arguments)) } var DPGlobal = { modes: [{ clsName: "days", navFnc: "UTCMonth", navStep: 1 }, { clsName: "months", navFnc: "UTCFullYear", navStep: 1 }, { clsName: "years", navFnc: "UTCFullYear", navStep: 10 }], isLeapYear: function (year) { return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0 }, getDaysInMonth: function (year, month) { return [31, DPGlobal.isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month] }, headTemplate: "<thead>" + "<tr>" + '<th class="prev">&lsaquo;</th>' + '<th colspan="5" class="switch"></th>' + '<th class="next">&rsaquo;</th>' + "</tr>" + "</thead>", contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>' }; DPGlobal.template = '<div class="datepicker-days">' + '<table class="table-condensed">' + DPGlobal.headTemplate + "<tbody></tbody>" + "</table>" + "</div>" + '<div class="datepicker-months">' + '<table class="table-condensed">' + DPGlobal.headTemplate + DPGlobal.contTemplate + "</table>" + "</div>" + '<div class="datepicker-years">' + '<table class="table-condensed">' + DPGlobal.headTemplate + DPGlobal.contTemplate + "</table>" + "</div>"; var TPGlobal = { hourTemplate: '<span data-action="showHours" data-time-component="hours" class="timepicker-hour"></span>', minuteTemplate: '<span data-action="showMinutes" data-time-component="minutes" class="timepicker-minute"></span>', secondTemplate: '<span data-action="showSeconds" data-time-component="seconds" class="timepicker-second"></span>' }; TPGlobal.getTemplate = function (is12Hours, showSeconds) { return '<div class="timepicker-picker">' + '<table class="table-condensed"' + (is12Hours ? ' data-hour-format="12"' : "") + ">" + "<tr>" + '<td><a href="#" class="btn" data-action="incrementHours"><i class="icon-chevron-up"></i></a></td>' + '<td class="separator"></td>' + '<td><a href="#" class="btn" data-action="incrementMinutes"><i class="icon-chevron-up"></i></a></td>' + (showSeconds ? '<td class="separator"></td>' + '<td><a href="#" class="btn" data-action="incrementSeconds"><i class="icon-chevron-up"></i></a></td>' : "") + (is12Hours ? '<td class="separator"></td>' : "") + "</tr>" + "<tr>" + "<td>" + TPGlobal.hourTemplate + "</td> " + '<td class="separator">:</td>' + "<td>" + TPGlobal.minuteTemplate + "</td> " + (showSeconds ? '<td class="separator">:</td>' + "<td>" + TPGlobal.secondTemplate + "</td>" : "") + (is12Hours ? '<td class="separator"></td>' + "<td>" + '<button type="button" class="btn btn-primary" data-action="togglePeriod"></button>' + "</td>" : "") + "</tr>" + "<tr>" + '<td><a href="#" class="btn" data-action="decrementHours"><i class="icon-chevron-down"></i></a></td>' + '<td class="separator"></td>' + '<td><a href="#" class="btn" data-action="decrementMinutes"><i class="icon-chevron-down"></i></a></td>' + (showSeconds ? '<td class="separator"></td>' + '<td><a href="#" class="btn" data-action="decrementSeconds"><i class="icon-chevron-down"></i></a></td>' : "") + (is12Hours ? '<td class="separator"></td>' : "") + "</tr>" + "</table>" + "</div>" + '<div class="timepicker-hours" data-action="selectHour">' + '<table class="table-condensed">' + "</table>" + "</div>" + '<div class="timepicker-minutes" data-action="selectMinute">' + '<table class="table-condensed">' + "</table>" + "</div>" + (showSeconds ? '<div class="timepicker-seconds" data-action="selectSecond">' + '<table class="table-condensed">' + "</table>" + "</div>" : "") } })(window.jQuery);